#pragma once

enum PacketType
{
  PT_UNKNOWN,
  PT_SYN,
  PT_SYNACK,
  PT_ACK,
  PT_MSG
};

struct RUdpPacket
{
  RUdpPacket()
    : mSeqId(0)
    , mAckId(0)
    , mPacketType(PT_UNKNOWN)
    , mPayload(0)
    , mPayloadLen(0)
  {
    mTimeStamp = timeGetTime();
  }

  ~RUdpPacket()
  {
    delete[] mPayload;
  }

  size_t ToBuffer(char* buffer, size_t length) const
  {
    size_t index = 0;

    memcpy(&buffer[index], &mPacketType, sizeof(mPacketType));
    index += sizeof(mPacketType);

    memcpy(&buffer[index], &mSeqId, sizeof(mSeqId));
    index += sizeof(mSeqId);

    memcpy(&buffer[index], &mAckId, sizeof(mAckId));
    index += sizeof(mAckId);

    memcpy(&buffer[index], &mTimeStamp, sizeof(mTimeStamp));
    index += sizeof(mTimeStamp);

    memcpy(&buffer[index], &mPayloadLen, sizeof(mPayloadLen));
    index += sizeof(mPayloadLen);

    _ASSERT( mPayloadLen + index <= length );

    memcpy(&buffer[index], mPayload, mPayloadLen);
    index += mPayloadLen;

    return index;
  }

  void FromBuffer(const char* buffer, size_t length)
  {
    size_t index = 0;

    memcpy(&mPacketType, &buffer[index], sizeof(mPacketType));
    index += sizeof(mPacketType);

    memcpy(&mSeqId, &buffer[index], sizeof(mSeqId));
    index += sizeof(mSeqId);

    memcpy(&mAckId, &buffer[index], sizeof(mAckId));
    index += sizeof(mAckId);

    memcpy(&mTimeStamp, &buffer[index], sizeof(mTimeStamp));
    index += sizeof(mTimeStamp);

    memcpy(&mPayloadLen, &buffer[index], sizeof(mPayloadLen));
    index += sizeof(mPayloadLen);

    delete [] mPayload;

    if ( mPayloadLen )
    {
      mPayload = new char[mPayloadLen];
      memcpy(mPayload, &buffer[index], mPayloadLen);
    }
  }

  PacketType mPacketType;
  int mSeqId;
  int mAckId;
  DWORD mTimeStamp;
  char* mPayload;
  int mPayloadLen;
};
